﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Project362.Collections;
using Project362.Tags;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;

namespace Project362.Files
{
    public enum FileType
    {
        DOCUMENT,
        IMAGE,
        CODE,
        EXECUTABLE,
        RESOURCE,
        UNSET
    }
    [Serializable()]
    public class FileClass : ISerializable
    {

		private MetaHandler metas;
        private string filename;
        private string name;
        private string collection;
        private FileType filetype;
        /// <summary>
        /// Location of the file on the system
        /// </summary>
        public string Filename { get { return this.filename; } }
        public string Name { get { return this.name; } }
        public string Collection { get { return this.collection; } }
        public FileType Filetype { get { return this.filetype; } set { this.filetype = value; } }
		private List<Tag> tags;
        /// <summary>
        /// Initializes a new file
        /// </summary>
        /// <param name="filename">Location of file</param>
        public FileClass(string filename, string name, string collection)
        {
            this.filename = filename;
            this.name = name;
			this.tags=new List<Tag>();
			this.metas=new MetaHandler();
            this.filetype = FileType.UNSET;
            this.collection = collection;
        }
        public FileClass(SerializationInfo info, StreamingContext stream){
            this.metas=(MetaHandler)info.GetValue("MetaHandler",typeof(MetaHandler));
            this.filename=(string)info.GetValue("Filename",typeof(string));
            this.name=(string)info.GetValue("Name",typeof(string));
            this.filetype=(FileType)info.GetValue("FileType",typeof(FileType));
            this.tags=(List<Tag>)info.GetValue("Tags",typeof(List<Tag>));
            this.collection=(string)info.GetValue("Collection",typeof(string));
        }
        public bool Open()
        {
            try
            {
                System.Diagnostics.Process.Start(@filename);
            }
            catch (FileNotFoundException e)
            {
                return false;
            }
            return true;
        }

        public bool Delete(Collection owner)
        {
            try
            {
                owner.removeFile(this);
                File.Delete(@filename);
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        public bool Copy(string dest)
        {
            try
            {
                int addon=1;
                string test=filename;
                while (File.Exists(@dest+@test))
                {
                    test = filename + addon++;
                }
                File.Copy(@filename, @dest);
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        public bool MoveFile(string dest)
        {
            try
            {
                File.Move(@filename, @dest);
                filename = dest;
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
        public List<string> getMetadataKeys()
        {
            return this.metas.getAllKeys();
        }
        public List<string> getMetas()
        {
            return metas.getAll();
        }
        public bool Convert(string format)
        {
            try
            {
                Image loaded = Image.FromFile(@filename);
                switch (this.filetype)
                {
                    case FileType.IMAGE:
                        switch (format)
                        {
                            case "bmp":
                                File.Delete(@filename);
                                filename = System.IO.Path.GetFileNameWithoutExtension(name);
                                filename += ".bmp";
                                loaded.Save(@filename, ImageFormat.Bmp);
                                break;
                            case "gif":
                                File.Delete(@filename);
                                filename = System.IO.Path.GetFileNameWithoutExtension(name);
                                filename += ".gif";
                                loaded.Save(@filename, ImageFormat.Gif);
                                break;
                            case "jpg":
                                File.Delete(@filename);
                                filename = System.IO.Path.GetFileNameWithoutExtension(name);
                                filename += ".jpg";
                                loaded.Save(@filename, ImageFormat.Jpeg);
                                break;
                        }
                        break;
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
		public bool addTag(Tag t){
			if(!tags.Contains(t)){
				tags.Add(t);
				return true;
			} else return false;
		}
		public bool removeTag(Tag t){
			if(tags.Contains(t)){
				tags.Remove(t);
				return true;
			} else return false;
		}
        public List<Tag> getTags()
        {
            return this.tags;
        }
        public bool addAttribute(string name, string content)
        {
	        return metas.addAttribute(name, content);
        }
        public bool editAttributeContent(string name, string content)
        {
	        return metas.editAttributeContent(name, content);
        }
        public bool removeAttribute(string name)
        {
	        return metas.removeAttribute(name);
        }
        public string getMetadataContents(string meta)
        {
            return metas.getMetadataContents(meta);
        }
        public void GetObjectData(SerializationInfo info, StreamingContext stream)
        {
            info.AddValue("MetaHandler", metas);
            info.AddValue("Filename", filename);
            info.AddValue("Name", name);
            info.AddValue("FileType", filetype);
            info.AddValue("Tags", tags);
            info.AddValue("Collection", collection);
        }
    }
}
